from datetime import datetime, timedelta
from common.const import IntervalType


def get_interval_end_pair(interval_type, base_time, last_window, week_start=0, calc_full_range=None):
    assert isinstance(interval_type, IntervalType)
    if not base_time:
        base_time = datetime.now()
    assert isinstance(base_time, datetime)
    if last_window or calc_full_range:
        start_time, end_time = _get_last_interval_pair(interval_type, base_time, last_window, week_start)
    else:
        start_time, end_time = _get_current_interval_pair(interval_type, base_time, week_start)
    return start_time, end_time


def _get_last_interval_pair(interval_type, base_time, last_delta=1, week_start=0):
    if interval_type == IntervalType.HOUR:
        last_base_time = base_time - timedelta(hours=last_delta)
        last_end_time = last_base_time + timedelta(hours=1)
        return datetime(last_base_time.year, last_base_time.month, last_base_time.day,
                        hour=last_base_time.hour), datetime(last_end_time.year, last_end_time.month, last_end_time.day,
                                                            last_end_time.hour)
    elif interval_type == IntervalType.DAY:
        last_base_time = base_time - timedelta(days=last_delta)
        last_end_time = last_base_time + timedelta(days=1)
        return datetime(last_base_time.year, last_base_time.month, last_base_time.day), datetime(last_end_time.year,
                                                                                                 last_end_time.month,
                                                                                                 last_end_time.day)
    elif interval_type == IntervalType.WEEK:
        if base_time.weekday() < week_start - 1:
            last_delta += 1
        last_base_time = base_time - timedelta(days=7*last_delta)
        start_time = datetime(last_base_time.year, last_base_time.month, last_base_time.day) - timedelta(
            days=last_base_time.weekday()) + timedelta(days=(week_start-1))
        return start_time, start_time + timedelta(days=7),

    elif interval_type == IntervalType.MONTH:
        if base_time.month <= last_delta:
            diff = last_delta - base_time.month
            year_diff, month_diff = int(diff / 12) + 1, diff % 12
            start_time = datetime(base_time.year - year_diff, 12 - month_diff, 1)
        else:
            start_time = datetime(base_time.year, base_time.month - last_delta, 1)
        if start_time.month == 12:
            end_time = datetime(base_time.year + 1, 1, 1)
        else:
            end_time = datetime(start_time.year, start_time.month + 1, 1)
        return start_time, end_time

    elif interval_type == IntervalType.ALL_TIME:
        return datetime.now() - timedelta(days=10000), datetime.now()


def _get_current_interval_pair(interval_type, base_time, week_start=0):
    if interval_type == IntervalType.HOUR:
        return base_time.replace(minute=0, second=0, microsecond=0), base_time
    elif interval_type == IntervalType.DAY:
        return base_time.replace(hour=0, minute=0, second=0, microsecond=0), base_time
    elif interval_type == IntervalType.WEEK:
        if base_time.weekday() < week_start - 1:
            start_time = (base_time - timedelta(days=base_time.weekday()) + timedelta(days=(week_start-1)) -
                          timedelta(days=7)).replace(hour=0, minute=0, second=0, microsecond=0)
        else:
            start_time = (base_time - timedelta(days=base_time.weekday()) + timedelta(days=(week_start-1))).replace(
                hour=0, minute=0, second=0, microsecond=0)
        end_time = base_time
        return start_time, end_time
    elif interval_type == IntervalType.MONTH:
        return (base_time - timedelta(days=base_time.day - 1)).replace(hour=0, minute=0, second=0,
                                                                       microsecond=0), base_time
    elif interval_type == IntervalType.ALL_TIME:
        return datetime.now() - timedelta(days=1000), datetime.now()
